/**
 * @file app\tasks\mobus\devices\_config_device.c
 *
 * Copyright (C) 2023
 *
 * _config_device.c is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 * @author HinsShum hinsshum@qq.com
 *
 * @encoding utf-8
 */
#include "storage.h"
/*---------- includes ----------*/
/*---------- macro ----------*/
/*---------- type define ----------*/
/*---------- variable prototype ----------*/
/*---------- function prototype ----------*/
/*---------- variable ----------*/
struct storage_mobus_groups_info* t_groups = NULL;
/*---------- function ----------*/
static void __clean_group_by_adress(void) {
    for (uint16_t i = 0; i < CONFIG_STORAGE_MOBUS_GROUP_NUMS; i++) {
        t_groups->groups[i].uid = 0xFFFF;
        t_groups->groups[i].bits = 0x00;
    }
    storage_set(STORAGE_AREA_MOBUS_GROUPS, t_groups, sizeof(struct storage_mobus_groups_info));
}
static void _config_device(mobus_device_t self, uint8_t channel,
    uint8_t devaddr, uint16_t devtype,
    uint8_t channel_nums) {
    struct storage_mobus_device* temp = NULL;
    char channl_id = 0;
    temp = (struct storage_mobus_device*)storage_get(STORAGE_AREA_DEVICE);
    assert(temp);
    t_groups = (struct storage_mobus_groups_info*)storage_get(STORAGE_AREA_MOBUS_GROUPS);
    assert(t_groups);

    if (devtype == MOBUS_DEVICE_TYPE_UNKNOWN) {
        if (no_storage.allocate_adr_dly != 0) {
            no_storage.allocate_adr_dly = 0;
            temp->device.native_address = devaddr;
            __clean_group_by_adress();
            storage_set(STORAGE_AREA_DEVICE, temp, sizeof(struct storage_mobus_device));
            self->get_device_data(self);
            self->req_access_to_mobus_network(self);
        }
    }
    else {
        channl_id = channel & 0x0F;
        if (channl_id == 0) {
            goto REBACK;
        }
        else if (channl_id < 4) {
            if (devtype == MOBUS_DEVICE_TYPE_NOMAL_LIGHT ||
                devtype == MOBUS_DEVICE_TYPE_WATER_HEATER ||
                devtype == MOBUS_DEVICE_TYPE_ELECTRIC_COOKER ||
                devtype == MOBUS_DEVICE_TYPE_RANGE_HOOD ||
                devtype == MOBUS_DEVICE_TYPE_WASHING_MACHINE ||
                devtype == MOBUS_DEVICE_TYPE_ICEBOX ||
                devtype == MOBUS_DEVICE_TYPE_ELECTRONIC_TOILET ||
                devtype == MOBUS_DEVICE_TYPE_FISH_TANK ||
                devtype == MOBUS_DEVICE_TYPE_UNKNOWN)
                temp->device.channel_type[channl_id] = devtype;
        }
        else {
            temp->device.native_address = devaddr;
            __clean_group_by_adress();
        }
        storage_set(STORAGE_AREA_DEVICE, temp, sizeof(struct storage_mobus_device));
REBACK:
        self->get_device_data(self);
        self->req_access_to_mobus_network(self);
    }
}
